﻿// -----------------------------------------------------------------------
// <copyright file="IMG_Morphology.cs" company="Hewlett-Packard">
// TODO: Update copyright text.
// </copyright>
// -----------------------------------------------------------------------

namespace ImageProcessing.ImageProcessor
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public static class IMG_Morphology
    {
        /// <summary>
        /// Dilations the specified org image.
        /// </summary>
        /// <param name="orgImage">The org image.</param>
        /// <param name="mask">The mask.</param>
        /// <param name="originX">The x origin.</param>
        /// <param name="originY">The y origin.</param>
        /// <returns>eruded image</returns>
        public static Entities.IMG_Image Erosion(int[,] orgImage, int[,] mask, int originX, int originY)
        {
            try
            {
                int width = mask.GetLength(1) - 1;
                int height = mask.GetLength(0) - 1;
                Entities.IMG_Image returnedImage = new Entities.IMG_Image(orgImage.GetLength(1), orgImage.GetLength(0));

                int maskWidth = mask.GetLength(1) - 1;
                int maskHeight = mask.GetLength(0) - 1;

                for (int i = 0; i < orgImage.GetLength(0); i++)
                {
                    for (int j = 0; j < orgImage.GetLength(1); j++)
                    {
                        bool found = false;

                        for (int k = -originX; k <= maskWidth - originX; k++)
                        {
                            for (int l = -originY; l <= maskHeight - originY; l++)
                            {
                                int imageXindex = j + k;
                                int imageYindex = i + l;
                                if (imageXindex >= 0 && imageXindex < orgImage.GetLength(1) && imageYindex >= 0 && imageYindex < orgImage.GetLength(0))
                                {
                                    if (mask[l + originY, k + originX] == 1 && orgImage[imageYindex, imageXindex] != mask[l + originY, k + originX])
                                    {
                                        found = true;
                                        goto label;
                                    }
                                }
                            }
                        }

                    label:
                        if (!found)
                        {
                            returnedImage[i, j] = new Entities.Pixel(255, 255, 255);
                        }
                        else
                        {
                            returnedImage[i, j] = new Entities.Pixel(0, 0, 0);
                        }
                    }
                }

                return returnedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// Dilations the specified org image.
        /// </summary>
        /// <param name="orgImage">The org image.</param>
        /// <param name="mask">The mask.</param>
        /// <param name="originX">The origin X.</param>
        /// <param name="originY">The origin Y.</param>
        /// <returns>the dilated image</returns>
        public static Entities.IMG_Image Dilation(int[,] orgImage, int[,] mask, int originX, int originY)
        {
            try
            {
                int width = mask.GetLength(1) - 1;
                int height = mask.GetLength(0) - 1;
                Entities.IMG_Image returnedImage = new Entities.IMG_Image(orgImage.GetLength(1), orgImage.GetLength(0));
                int[,] reversedMask = new int[height + 1, width + 1];

                for (int i = 0; i < height + 1; i++)
                {
                    int front = 0;
                    int rear = width;
                    while (front <= rear)
                    {
                        reversedMask[i, front] = mask[i, rear];
                        reversedMask[i, rear] = mask[i, front];
                        front++;
                        rear--;
                    }
                }

                for (int i = 0; i < width + 1; i++)
                {
                    int front = 0;
                    int rear = height;
                    while (front <= rear)
                    {
                        reversedMask[front, i] = mask[rear, i];
                        reversedMask[rear, i] = mask[front, i];
                        front++;
                        rear--;
                    }
                }

                int xOr = width - originX;
                int yOr = height - originY;

                int maskWidth = mask.GetLength(1) - 1;
                int maskHeight = mask.GetLength(0) - 1;

                for (int i = 0; i < orgImage.GetLength(0); i++)
                {
                    for (int j = 0; j < orgImage.GetLength(1); j++)
                    {
                        bool found = false;

                        for (int k = -xOr; k <= maskWidth - xOr; k++)
                        {
                            for (int l = -yOr; l <= maskHeight - yOr; l++)
                            {
                                int imageXindex = j + k;
                                int imageYindex = i + l;
                                if (imageXindex >= 0 && imageXindex < orgImage.GetLength(1) && imageYindex >= 0 && imageYindex < orgImage.GetLength(0))
                                {
                                    if (orgImage[imageYindex, imageXindex] == reversedMask[l + yOr, k + xOr] && reversedMask[l + yOr, k + xOr] == 1)
                                    {
                                        found = true;
                                        goto label;
                                    }
                                }
                            }
                        }

                    label:
                        if (found)
                        {
                            returnedImage[i, j] = new Entities.Pixel(255, 255, 255);
                        }
                        else
                        {
                            returnedImage[i, j] = new Entities.Pixel(0, 0, 0);
                        }
                    }
                }

                return returnedImage;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
